package cn.atzxc.qy.service.impl;

import cn.atzxc.qy.domain.*;
import cn.atzxc.qy.domain.vo.OrderVo;
import cn.atzxc.qy.domain.vo.TaskVo;
import cn.atzxc.qy.mapper.OrderMapper;
import cn.atzxc.qy.mapper.RiderMapper;
import cn.atzxc.qy.mapper.TaskMapper;
import cn.atzxc.qy.mapper.UserMapper;
import cn.atzxc.qy.service.OrderService;
import cn.atzxc.qy.utils.JwtUtil;
import cn.atzxc.qy.utils.NumberGenerator;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import io.jsonwebtoken.Claims;
import org.apache.ibatis.javassist.NotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

/**
 * 1.生成订单：
 *      用户在下单时，小程序前端向后端发送订单信息。
 *      后端接收到订单信息后，将订单数据存入数据库，同时订单状态设置为待支付。
 * 2.调起支付：
 *      小程序前端收到后端返回的订单信息后，调用微信支付接口，传递订单信息进行支付。
 * 3.支付成功：
 *      用户在微信支付授权界面确认支付后，微信服务器会向你预先设置的支付结果通知接口发送支付结果。
 *      后端接收到支付结果通知后，验证支付结果的合法性，确保支付金额和订单信息一致。
 *      如果支付成功，后端更新数据库中对应订单的状态为已支付，并记录支付成功的相关信息（如支付时间、交易流水号等）。
 * 4.支付失败：
 *      如果支付失败，后端也会更新订单状态为支付失败，并记录失败的相关信息。
 * 5.订单查询和管理：
 *      在用户和商家界面，可以提供订单查询和管理功能，用户和商家可以随时查看订单状态和支付详情。
 *      后端提供相应的接口，用于查询订单信息、订单状态的更新等操作。
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private TaskMapper taskMapper;
    @Autowired
    private UserMapper userMap;
    @Autowired
    private RiderMapper riderMapper;

    /**
     * 新增一条订单信息
     * @param token
     * @param order
     * @param taskVo
     * @return
     */
    @Override
    @Transactional
    public Boolean insertOrder(String token, Order order, TaskVo taskVo) throws Exception {

        //1.获取骑手ID -- 通过token解析出当前登录的用户ID就是骑手
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        Long userid = Long.parseLong(subject);//封装成为一个long类型
        order.setCourierId(userid);//设置骑手ID
        //TODO 后面对骑手ID进行判断，判断是否为已经认证的骑手，
        //          如果是已经认证的骑手，则可以接单
        //          如果不是骑手，则提示去认证骑手
//        OrderServiceImpl orderServiceImpl = new OrderServiceImpl();
//        Boolean rider = orderServiceImpl.isRider(token);


        //2.通过ID判断骑手是否认证
        LambdaQueryWrapper<Rider> queryWrap = new LambdaQueryWrapper<>();
        queryWrap.eq(Rider::getUserId,userid);
        Rider rider = riderMapper.selectOne(queryWrap);
        System.out.println("获取到的rider为："+rider);
        Boolean isRider=false;
        if(rider == null){//说明该用户未认证
            System.out.println("用户为空");
            isRider = false;
        }else {
            if(rider.getAuthStatus().equals("已认证")){
                isRider = true;
            }else {
                System.out.println("不相等");
                isRider = false;
            }
        }


        System.out.println("骑手认证状态："+rider+"布尔指为："+isRider);
        if(isRider){
            //2.生成订单编号
            String ordercode = NumberGenerator.generateOrderNumber();
            order.setOrderCode(ordercode);

            //3.设置订单状态 - 初始为进行中
            order.setOrderStatus("待收货");

            //4.设置一个创建时间，new Date()
            Date date = NumberGenerator.generateCurrentDateTime();
            order.setOrderCreateTime(date);

            System.out.println("封装后的order为："+order);

            //插入订单数据
            int insert = orderMapper.insert(order);
            Long taskId = taskVo.getTaskId();
            //更新任务状态为已接单
            UpdateWrapper<Task> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("task_id", taskId); // 设置条件：taskId字段的值等于指定的taskId
            updateWrapper.set("task_status", "已接单"); // 设置要更新的字段和新值
            int update = taskMapper.update(null, updateWrapper);
            System.out.println("到这里了");
            return true;
        }
        return false;
    }

    @Override
    public OrderVo selectOneByTaskId(Long taskid) {
        OrderVo orderVo = orderMapper.selectOneByTaskId(taskid);
        return orderVo;
    }

    @Override
    public OrderVo selectOneByUserId(Long orderId) {
        OrderVo orderVo = orderMapper.selectOneByUserId(orderId);
        return orderVo;
    }

    /**
     * 我已到达：修改订单状态为：已送达
     * @param orderid
     * @return
     */
    @Override
    @Transactional
    public int alreayArrived(String token,Long orderid,Long taskid) throws Exception {

        //解析出用户USERID
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        Long userid = Long.parseLong(subject);//封装成为一个long类型

        //判断点击我已送达的用户是否为骑手
        // 1.通过传递的订单ID，查询出骑手ID
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getCourierId, userid);
        queryWrapper.eq(Order::getOrderId,orderid);
        Order order = orderMapper.selectOne(queryWrapper);
        if(order == null){
            System.out.println("该用户不是骑手，错误操作");
            return -1;//表示该用户不是骑手
        }
        System.out.println("获取到的订单对象为："+order.toString());

        //更新订单状态为已送达 - 进入确认收货阶段
        UpdateWrapper<Order> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_id", orderid); // 设置条件：taskId字段的值等于指定的taskId
        updateWrapper.set("order_status", "已送达"); // 设置要更新的字段和新值
        int update = orderMapper.update(null, updateWrapper);

        //更新任务状态为已送达 - 等待用户确认收货 - 当用户确认收货后进入完成阶段
        UpdateWrapper<Task> updateWrapper1 = new UpdateWrapper<>();
        updateWrapper1.eq("task_id", taskid); // 设置条件：taskId字段的值等于指定的taskId
        updateWrapper1.set("task_status", "已送达"); // 设置要更新的字段和新值
        int update1 = taskMapper.update(null, updateWrapper1);


        return update+update1;
    }


    /**
     * 查询等待收货得数据
     * 1.通过token解析出用户ID
     * 2.等待收货说明用户是本人userid
     * 3.通过查看orders表中的userid==传递进来得ID
     * @param token
     * @return
     */
    @Override
    public List<OrderVo> selectWaitGet(String token) throws Exception {

        //1.获取当前用户的ID
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        Long userid = Long.parseLong(subject);//封装成为一个long类型
        //2.通过userid查看数据
        List<OrderVo> orderVos = orderMapper.selectOrderInfoByUserId(userid);

        return orderVos;
    }

    /**
     * 我是骑手 查询正在配送的数据
     *
     * @param token
     * @return
     */
    @Override
    public List<OrderVo> selectOrderInfoByQiId(String token) throws Exception {

        //1.获取当前用户的ID
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        Long userid = Long.parseLong(subject);//封装成为一个long类型
        //2.通过userid查看数据
        List<OrderVo> orderVos = orderMapper.selectOrderInfoByQiId(userid);

        return orderVos;
    }
    /**
     * 属于我的已经完成的订单
     *
     * @param token
     * @return
     */
    @Override
    public List<OrderVo> selectOrderInfoByWanCheng(String token) throws Exception {

        //1.获取当前用户的ID
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        Long userid = Long.parseLong(subject);//封装成为一个long类型
        //2.通过userid查看数据
        List<OrderVo> orderVos = orderMapper.selectOrderInfoByWanCheng(userid);

        return orderVos;
    }

    /**
     * 查询出属于我的所有订单
     *
     * @param token
     * @return
     */
    @Override
    public List<OrderVo> selectAllOrderInfo(String token) throws Exception {

        //1.获取当前用户的ID
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        Long userid = Long.parseLong(subject);//封装成为一个long类型
        //2.通过userid查看数据
        List<OrderVo> orderVos = orderMapper.selectAllOrderInfo(userid);

        return orderVos;
    }

    /**
     * 查询出所有的属于我的售后中的订单
     *
     * @param token
     * @return
     */
    @Override
    public List<OrderVo> selectOrderInfoByShouHou(String token) throws Exception {

        //1.获取当前用户的ID
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        Long userid = Long.parseLong(subject);//封装成为一个long类型
        //2.通过userid查看数据
        List<OrderVo> orderVos = orderMapper.selectOrderInfoByShouHou(userid);

        return orderVos;
    }

    /**
     * 确认收货操作
     * 1.判断当前用户和订单对象中的发布者是否为同一个用户
     *      如果相同，则执行第二步
     *      如果不同，则返回400，并填写非法操作
     * 2.讲订单中的状态字段，设置为已完成，说明用户已经点击了确认收货
     * 3.讲任务中的状态字段，设置为已完成，说明该任务已经关闭，开始进售后阶段
     * 4.将订单中的价格字段中的值，等值加入到该订单中骑手ID对应的用户表中的余额字段
     *
     * 以上如果有一步出现异常，则进行退
     * @param token
     * @param orderVo
     * @return
     */
    @Override
    @Transactional
    public int sureArrive(String token, OrderVo orderVo) throws Exception {
        //1.获取当前用户的ID
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        Long userid = Long.parseLong(subject);//封装成为一个long类型
        if(!userid.equals(orderVo.getUserId())){
            System.out.println("前端传递的用户ＩＤ　"+orderVo.getUserId());
            return 0;
        }
        System.out.println("此订单属于该用户");
        //该订单是该用户的订单
        //将订单中的状态字段，设置为已完成，说明用户已经点击了确认收货
        UpdateWrapper<Order> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_id", orderVo.getOrderId()); // 设置条件
        updateWrapper.set("order_status", "已完成"); // 设置要更新的字段和新值
        int update = orderMapper.update(null, updateWrapper);

        //将任务中的状态字段，设置为已完成，说明该任务已经关闭，开始进售后阶段
        UpdateWrapper<Task> updateWrapper1 = new UpdateWrapper<>();
        updateWrapper1.eq("task_id", orderVo.getTaskId()); // 设置条件
        updateWrapper1.set("task_status", "已完成"); // 设置要更新的字段和新值
        int update1 = taskMapper.update(null, updateWrapper1);

        //将订单中的价格字段中的值，等值加入到该订单中骑手ID对应的用户表中的余额字段
        UpdateWrapper<User> updateWrapper2 = new UpdateWrapper<>();
        updateWrapper2.eq("user_id", orderVo.getCourierId()); // 设置条件
        updateWrapper2.setSql("balance = balance + "+orderVo.getOrderReward());
        int update2 = userMap.update(null, updateWrapper2);


        return update1+update;
    }


    //通过token判断该用户是否为骑手
    @Override
    public Boolean isRider(String token) throws Exception {

        //1.获取到传递的ID
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        Long userid = Long.parseLong(subject);//封装成为一个long类型

        //2.通过ID判断
        LambdaQueryWrapper<Rider> queryWrap = new LambdaQueryWrapper<>();
        queryWrap.eq(Rider::getUserId,userid);
        Rider rider = riderMapper.selectOne(queryWrap);
        System.out.println("获取到的rider为："+rider);
        if(rider == null){//说明该用户未认证
            return false;
        }else {
            return rider.getAuthStatus() == "已认证"? true:false;
        }

    }

    @Override
    public Long[] selectOrderCount(String token) throws Exception {

        //1.获取到传递的ID
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        Long userid = Long.parseLong(subject);//封装成为一个long类型

        //查询待收货订单
        LambdaQueryWrapper<Order> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(Order::getUserId,userid);
        queryWrapper1.eq(Order::getOrderStatus,"待收货");
        Long aLong1 = orderMapper.selectCount(queryWrapper1);

        //查询在配送订单
        LambdaQueryWrapper<Order> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(Order::getCourierId,userid);
        queryWrapper2.eq(Order::getOrderStatus,"待收货");
        Long aLong2 = orderMapper.selectCount(queryWrapper2);

        //查询已完成订单
        LambdaQueryWrapper<Order> queryWrapper3 = new LambdaQueryWrapper<>();
//        queryWrapper3.eq(Order::getOrderStatus,"已完成");
//        queryWrapper3.or(wrapper -> wrapper.eq(Order::getUserId, userid)
//                .or().eq(Order::getCourierId, userid));
        queryWrapper3.eq(Order::getOrderStatus, "已完成")
                .and(wrapper -> wrapper.eq(Order::getUserId, userid)
                        .or()
                        .eq(Order::getCourierId, userid));
        Long aLong3 = orderMapper.selectCount(queryWrapper3);

        //查询全部订单
        LambdaQueryWrapper<Order> queryWrapper4 = new LambdaQueryWrapper<>();
        queryWrapper4.or(wrapper -> wrapper.eq(Order::getUserId, userid)
                .or().eq(Order::getCourierId, userid));
        Long aLong4 = orderMapper.selectCount(queryWrapper4);

        // 声明并创建一个long数组，长度为5
        Long[] longs = new Long[5];

        // 为数组的每个元素赋值
        longs[0] = aLong1;
        longs[1] = aLong2;
        longs[2] = aLong3;
        longs[3] = aLong4;


        return longs;
    }
















}
